package advance.app.controller;

import advance.app.pojo.AppFileInfo;
import advance.app.pojo.DepFileInfo;
import advance.app.pojo.SopFileInfo;
import advance.app.service.impl.AppFileInfoServiceImpl;
import advance.app.service.impl.DepFileInfoServiceImpl;
import advance.app.service.impl.SopFileInfoServiceImpl;
import advance.app.utils.FileUpload;
import advance.app.utils.ZipUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.configurationprocessor.json.JSONArray;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Controller
@CrossOrigin
@RequestMapping("/")
public class IndexController {

    private static final Logger logger = LoggerFactory.getLogger(IndexController.class);

    @Value("${downpath.filepath12}")
    private String FILE_PATH12 = "C:\\";

    @Value("${downpath.winrarpath12}")
    private String WINRAR_PATH12 = "";

    @Value("${downpath.soppath12}")
    private String SOP_PATH12 = "";

    @Value("${downpath.pkgpath12}")
    private String PKG_PATH12 = "";

    @Value("${backupftp.localbackup12}")
    private String LOCAL_BACKUP12 = "";

    @Value("${backupftp.localsetup12}")
    private String LOCAL_SETUP12 = "";

    @Value("${backupftp.remotebackup12}")
    private String REMOTE_BACKUP12 = "";

    @Value("${backupftp.remotesetup12}")
    private String REMOTE_SETUP12 = "";

    @Value("${backupftp.basepath12}")
    private String BASE_PATH12 = "";

    /***************8Inch****************/
    @Value("${downpath.filepath8}")
    private String FILE_PATH8 = "C:\\";

    @Value("${downpath.winrarpath8}")
    private String WINRAR_PATH8 = "";

    @Value("${downpath.soppath8}")
    private String SOP_PATH8 = "";

    @Value("${downpath.pkgpath8}")
    private String PKG_PATH8 = "";

    @Value("${backupftp.localbackup8}")
    private String LOCAL_BACKUP8 = "";

    @Value("${backupftp.localsetup8}")
    private String LOCAL_SETUP8 = "";

    @Value("${backupftp.remotebackup8}")
    private String REMOTE_BACKUP8 = "";

    @Value("${backupftp.remotesetup8}")
    private String REMOTE_SETUP8 = "";

    @Value("${backupftp.basepath8}")
    private String BASE_PATH8 = "";

    @Value("${downpath.tempPath}")
    private String TMP_PATH = "C:\\";


    private static final String CSV_NAME = "MESProductList.csv";
    private static final String TMP = "TMP";
    private static final String ZIP_FILE = "ZIP_FILE";

    @Autowired
    AppFileInfoServiceImpl appFileInfoService;

    @Autowired
    SopFileInfoServiceImpl sopFileInfoService;

    @Autowired
    DepFileInfoServiceImpl depFileInfoService;

    @RequestMapping("/")
    public String home(){

        return "home";
    }

    @RequestMapping("/index/{name}")
    public String getFileType(Model model, @PathVariable("name") String name){
        System.out.println("getFileType:"+name.toLowerCase());
        model.addAttribute("file_type", name.toLowerCase());
        return "admins/downPage";
    }

    @ResponseBody
    @RequestMapping("/index/showData/{area}/{path}")
    public Map<String,Object> indexShowData(
            @PathVariable("area") String area,
            @PathVariable("path") String path,
            @RequestParam(required=false,defaultValue="1") int page,
            @RequestParam(required=false,defaultValue="15") int limit
    ){
        AppFileInfo data=appFileInfoService.getLatestInfoByType(area,path.toUpperCase());
        List<AppFileInfo> datas = new ArrayList<>();
        datas.add(data);
        int countx= 1;
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("code",0);
        map.put("msg","");
        map.put("count",countx);
        map.put("data",datas);
        System.out.println(map.toString());
        return map;
    }


    /**
     * @function 单文件上传TMP_PATH
     * @param file
     * @return
     */
    @PostMapping("/index/upload_one")
    @ResponseBody
    public Map<String,Object> UploadOne(MultipartFile file){
        Map<String,Object> result = new HashMap<>();
        if(file == null){
            result.put("status",false);
            result.put("code","fail");
            result.put("msg","上传失败！");
            return result;
        }else{
            Map<String, String> map = FileUpload.fileOne(file, TMP_PATH, FileUpload.FILE_TYPE);
            if(null != map && map.size()>0){
                result.put("status",true);
                result.put("code","success");
                result.put("url",map.get("fpath"));
                result.put("msg","success");
                return result;
            }else{
                result.put("status",false);
                result.put("code","fail");
                result.put("url","");
                result.put("msg","上传失败！");
                return result;
            }
        }
    }


    /**
     * 保存文件信息
     * @param info
     * @return
     */
    @PostMapping("/index/upload_save")
    @ResponseBody
    public Map<String,Object> UploadOneSave(AppFileInfo info){
        Map<String,Object> result = new HashMap<>();
        try {
            if(info == null){
                result.put("status",false);
                result.put("code",1);
                result.put("msg","上传失败！");
            }else{
                String filePath="",localBackUp="",winRarPath="",localSetUp="",basePath="";
                if(info.getAppArea().equals("8")){
                    filePath = FILE_PATH8;
                    localBackUp = LOCAL_BACKUP8;
                    winRarPath=WINRAR_PATH8;
                    localSetUp=LOCAL_SETUP8;
                    basePath=BASE_PATH8;
                }else if(info.getAppArea().equals("12")){
                    filePath = FILE_PATH12;
                    localBackUp = LOCAL_BACKUP12;
                    winRarPath=WINRAR_PATH12;
                    localSetUp=LOCAL_SETUP12;
                    basePath=BASE_PATH12;
                }
                AppFileInfo data = new AppFileInfo();
                String suffix = info.getPath().substring(info.getPath().lastIndexOf("."));
                String fileName = info.getPath().substring(info.getPath().lastIndexOf(FileUpload.SEPARATOR)+1, info.getPath().lastIndexOf("."));
                String[] fileNames = fileName.split(FileUpload.FILE_SPE);

                // XXX/WISE/TMP
                String unZipPath = filePath+FileUpload.SEPARATOR+TMP;

                // XXX/WISE/TMP/OPI
                String unZipPathProgress = unZipPath + FileUpload.SEPARATOR + info.getFileType();

                // XXX/WISE/ZIP_FILE/OPI/1.0.0.1/
                String destPath = filePath+FileUpload.SEPARATOR+ZIP_FILE+FileUpload.SEPARATOR+info.getFileType()+FileUpload.SEPARATOR+info.getVersion();

                // XXX/WISE/ZIP_FILE/OPI/1.0.0.1/OPI.zip
                String destFullPath = destPath+FileUpload.SEPARATOR+fileNames[0]+suffix;

                // XXX/OPI/1.0.0.1
                String localBackPath = localBackUp +FileUpload.SEPARATOR+info.getFileType()+FileUpload.SEPARATOR+info.getPrevVersion();

                if(null == info.getAppArea() || info.getAppArea().trim().equals("")){
                    result.put("status",false);
                    result.put("code",1);
                    result.put("msg","区域不能为空！");
                    return result;
                }
                data.setFileName(fileNames[0]+suffix);
                data.setFileType(info.getFileType().toUpperCase());
                data.setPath(destFullPath);
                // js里做了卡控版本
                data.setVersion(info.getVersion());
                data.setPrevVersion(info.getPrevVersion());
                data.setCreateTime(FileUpload.sdf.format(new Date()));  //fileNames[1].split(FileUpload.CHAR_ALT)[0]
                data.setSuffix(suffix);
                data.setAppArea(info.getAppArea());

                boolean flag=false,
                        isUnZip=false,
                        isBackUp=false,
                        isMoveSucc=false,
                        isCopyCsv=false,
                        isWriteCsv=false;

                flag = FileUpload.moveFile(info.getPath(),destFullPath);
                if(flag){
                    logger.debug(destFullPath+"FileUpload Success!");

                    if(info.getFileType().toUpperCase().equals("WISE_PKG")){  //WISE完整的安装包，只保存不解压，不存SetUp
                        isUnZip=true;
                        isBackUp=true;
                        isMoveSucc=true;
                        isCopyCsv=true;
                        isWriteCsv=true;
                    }else{
                        // 非WISE_PKG统一解压、备份、升级
                        isUnZip = ZipUtil.deCompress(destFullPath, unZipPath, winRarPath);
                        if(isUnZip){
                            logger.debug(destFullPath+"UnZip Success!");
                            String setUpFilePath = localSetUp+FileUpload.SEPARATOR+info.getFileType();
                            // 备份移动本地服务器Setup文件夹中对应的程序文件夹 setUpFilePath --> LocalBackUp
                            logger.info("move BackUp Folder:"+setUpFilePath+" --> "+localBackPath);
                            isBackUp = FileUpload.moveDirectoryToDirectory(setUpFilePath, localBackPath);
                            if(isBackUp){
                                String csvSuffix = CSV_NAME.substring(CSV_NAME.lastIndexOf("."));
                                String csvName = CSV_NAME.substring(CSV_NAME.lastIndexOf(FileUpload.SEPARATOR)+1, CSV_NAME.lastIndexOf("."));
                                String csvBackName = csvName+FileUpload.FILE_SPE+FileUpload.sdf.format(new Date());
                                // 备份成功后，移动解压后的文件到SetUp文件中  unZipPathProgress --> setUpFilePath
                                logger.info("移动解压后的文件到SetUp文件中:"+unZipPathProgress+" --> "+localSetUp);
                                isMoveSucc = FileUpload.moveDirectoryToDirectory(unZipPathProgress, localSetUp);
                                if(isMoveSucc){
                                    logger.info("copyFile:"+basePath+FileUpload.SEPARATOR+CSV_NAME+" --> "+localBackPath+FileUpload.SEPARATOR+csvBackName);
                                    isCopyCsv = FileUpload.copyFile(basePath+FileUpload.SEPARATOR+CSV_NAME,localBackPath+FileUpload.SEPARATOR+csvBackName);
                                    if(isCopyCsv){
                                        isWriteCsv = FileUpload.writeCsv(basePath+FileUpload.SEPARATOR+CSV_NAME, info.getFileType(), info.getVersion(),FileUpload.sdf2.format(new Date()));
                                    }
                                }else{  //移动失败，回退备份文件
                                    logger.info("Recover BackUp Folder:"+localBackPath+" --> "+setUpFilePath);
                                    isBackUp = FileUpload.moveDirectoryToDirectory(localBackPath, setUpFilePath);
                                }

                            }
                        }
                    }

                }else{
                    result.put("status",false);
                    result.put("code",1);
                    result.put("msg","上传失败！");
                }

                if(!flag || !isUnZip || !isBackUp || !isMoveSucc || !isCopyCsv || !isWriteCsv){
                    result.put("status",false);
                    result.put("code",1);
                    result.put("msg","处理失败！");
                }else{
                    appFileInfoService.saveAppFileInfo(data);
                    result.put("status",true);
                    result.put("code",0);
                    result.put("msg","上传成功！");
                }
            }
            return result;
        } catch (Exception e) {
            result.put("status",false);
            result.put("code",1);
            result.put("msg","上传失败！");
            e.printStackTrace();
            return result;
        }
    }

    @RequestMapping(value = "/index/uploadSopFolder", method = RequestMethod.POST)
    @ResponseBody
    public Map<String,Object> uploadSopFolder(@RequestParam(value = "sopFolder", required = true) MultipartFile[] sopFolder) {
        Map<String,Object> result = new HashMap<>();
        if(sopFolder == null){
            result.put("status",0);
            result.put("code","fail");
            result.put("path","");
            result.put("msg","上传失败！");
            return result;
        }else{
            // MES_MESClient_V1.0.zip  -->  /MES/Version/MesFile.zip
            Map<String,String> map = FileUpload.saveMultiFile(TMP_PATH+FileUpload.SEPARATOR+"SOP", sopFolder);
            if(null != map && map.size()>0){
                result.put("status",0);
                result.put("path",map.get("path"));
                result.put("code","success");
                result.put("msg","上传成功！");
                return result;
            }else{
                result.put("status",1);
                result.put("path","");
                result.put("code","fail");
                result.put("msg","上传失败！");
                return result;
            }
        }
    }

    @PostMapping("/index/getLastestVersion")
    @ResponseBody
    public Map<String,Object> getLastestVersion(String appArea,String fileType){
        logger.debug("getLastestVersion");
        Map<String,Object> result = new HashMap<>();

        try {
            AppFileInfo info = appFileInfoService.getLatestInfoByType(appArea,fileType);
            if (null == info){
                result.put("code",0);
                result.put("version","1.0.0.0");
            }else{
                result.put("code",0);
                result.put("version",info.getVersion());
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            result.put("code",1);
            result.put("version","0.0.0.0");
            return result;
        }
    }

    /**
     * @function SOP单文件上传
     * @param file
     * @return
     */
    @PostMapping("/index/upload_sop")
    @ResponseBody
    public Map<String,Object> SopUploadOne(MultipartFile file){
        Map<String,Object> result = new HashMap<>();
        if(file == null){
            result.put("status",false);
            result.put("code","fail");
            result.put("msg","上传失败！");
            return result;
        }else{

            Map<String, String> map = FileUpload.fileOne(file, TMP_PATH+FileUpload.SEPARATOR+"SOP", FileUpload.FILE_TYPE);
            if(null != map && map.size()>0){
                result.put("status",true);
                result.put("code","success");
                result.put("url",map.get("fpath"));
                result.put("msg","success");
                return result;
            }else{
                result.put("status",false);
                result.put("code","fail");
                result.put("url","");
                result.put("msg","上传失败！");
                return result;
            }
        }
    }

    /**
     * SOP版本和程序版本绑定
     * @param fileType
     * @return
     */
    @PostMapping("/index/getAllVersionByType")
    @ResponseBody
    public Map<String,Object> getAllVersionByType(String sopArea,String fileType){
        logger.debug("SOP-->getAllVersionByType");
        Map<String,Object> result = new HashMap<>();

        try {
            List<String> info = appFileInfoService.getAllVerInfoByType(sopArea,fileType)
                    .stream().distinct().collect(Collectors.toList());
            if (null == info){
                result.put("code",0);
                result.put("version","1.0.0.0");
            }else{
                result.put("code",0);
                result.put("version",info);
            }

            return result;
        } catch (Exception e) {
            e.printStackTrace();
            result.put("code",1);
            result.put("version","0.0.0.0");
            return result;
        }
    }

    /**
     * 保存SOP文件信息
     * @param info
     * @return
     */
    @PostMapping("/index/upload_sop_save")
    @ResponseBody
    public Map<String,Object> SopUploadOneSave(SopFileInfo info){
        Map<String,Object> result = new HashMap<>();
        try {
            if(info == null || info.getSopArea().trim().equals("")){
                result.put("status",false);
                result.put("code",1);
                result.put("msg","上传失败！");
            }else{
                String sopPath="";
                if(info.getSopArea().equals("8")){
                    sopPath = SOP_PATH8;
                }else if(info.getSopArea().equals("12")){
                    sopPath = SOP_PATH12;
                }

                List<String> paths = Arrays.asList(info.getSopPath().split(";"));
                List<SopFileInfo> listInfo = new ArrayList<>();
                for (int i = 0; i < paths.size(); i++) {
                    String path = paths.get(i);
                    String suffix = path.substring(path.lastIndexOf("."));
                    String fileName = path.substring(path.lastIndexOf(FileUpload.SEPARATOR)+1, path.lastIndexOf("."));
                    String[] fileNames = fileName.split(FileUpload.FILE_SPE);

                    // XXX/WISE/TMP
                    //String tmpPath = basePath+FileUpload.SEPARATOR+TMP;
                    // XXX/WISE/TMP/OPI
                    //String tmpFile = info.getSopPath();
                    // XXX/WISE/SOP/OPI/1.0.0.1/
                    String destPath = sopPath+FileUpload.SEPARATOR+info.getSopFileType()+FileUpload.SEPARATOR+info.getSopVersion();
                    // XXX/WISE/SOP/OPI/1.0.0.1/xxxx.pdf
                    String realName = fileNames[0].split(FileUpload.CHAR_ALT)[0]+suffix;
                    String destFullPath = destPath+FileUpload.SEPARATOR+realName;

                    boolean flag=false;
                    flag = FileUpload.moveFile(path,destFullPath);

                    if(!flag){
                        result.put("status",false);
                        result.put("code",0);
                        result.put("msg","移动文件失败，请检查Server文件！");
                        return result;
                    }
                    SopFileInfo data = new SopFileInfo();
                    data.setSopVersion(info.getSopVersion());
                    data.setSopFileType(info.getSopFileType());
                    data.setSopFileName(realName);
                    data.setSopPath(destFullPath);
                    data.setCreateTime(FileUpload.sdf.format(new Date()));
                    data.setSuffix(suffix);
                    data.setSopArea(info.getSopArea());
                    //listInfo.add(data);
                    sopFileInfoService.saveSopFileInfo(data);
                }

                if(true){
                    result.put("status",true);
                    result.put("code",0);
                    result.put("msg","上传成功！");
                }else{
                    result.put("status",false);
                    result.put("code",1);
                    result.put("msg","上传失败！");
                }

            }
            return result;
        } catch (Exception e) {
            result.put("status",false);
            result.put("code",1);
            result.put("msg","上传失败！");
            e.printStackTrace();
            return result;
        }
    }


    @RequestMapping(value = "/index/uploadDepFolder", method = RequestMethod.POST)
    @ResponseBody
    public Map<String,Object> uploadDepFolder(@RequestParam(value = "depFolder", required = true) MultipartFile[] depFolder) {
        Map<String,Object> result = new HashMap<>();
        if(depFolder == null){
            result.put("status",0);
            result.put("code","fail");
            result.put("path","");
            result.put("msg","上传失败！");
            return result;
        }else{
            // MES_MESClient_V1.0.zip  -->  /MES/Version/MesFile.zip
            Map<String,String> map = FileUpload.saveMultiFile(TMP_PATH+"DEP", depFolder);
            if(null != map && map.size()>0){
                result.put("status",0);
                result.put("path",map.get("path"));
                result.put("code","success");
                result.put("msg","上传成功！");
                return result;
            }else{
                result.put("status",1);
                result.put("path","");
                result.put("code","fail");
                result.put("msg","上传失败！");
                return result;
            }
        }
    }

    /**
     * 保存DEP包文件信息
     * @param info
     * @return
     */
    @PostMapping("/index/upload_dep_save")
    @ResponseBody
    public Map<String,Object> DepUploadOneSave(DepFileInfo info){
        Map<String,Object> result = new HashMap<>();
        try {
            if(info == null || info.getDepArea().trim().equals("")){
                result.put("status",false);
                result.put("code",1);
                result.put("msg","上传失败！");
            }else{
                String pkgPath="";
                if(info.getDepArea().equals("8")){
                    pkgPath = PKG_PATH8;
                }else if(info.getDepArea().equals("12")){
                    pkgPath = PKG_PATH12;
                }
                List<String> paths = Arrays.asList(info.getDepPath().split(";"));
                List<SopFileInfo> listInfo = new ArrayList<>();
                for (int i = 0; i < paths.size(); i++) {
                    String path = paths.get(i);
                    String suffix = path.substring(path.lastIndexOf("."));
                    String fileName = path.substring(path.lastIndexOf(FileUpload.SEPARATOR)+1, path.lastIndexOf("."));
                    String[] fileNames = fileName.split(FileUpload.FILE_SPE);

                    // XXX/WISE/TMP
                    //String tmpPath = FILE_PATH12+FileUpload.SEPARATOR+TMP;
                    // XXX/WISE/TMP/OPI
                    //String tmpFile = path;
                    // XXX/WISE/DEP/OPI/1.0.0.1/
                    String destPath = pkgPath+FileUpload.SEPARATOR+info.getDepFileType();
                    // XXX/WISE/DEP/OPI/1.0.0.1/xxxx.pdf
                    String realName = fileNames[0].split(FileUpload.CHAR_ALT)[0]+suffix;
                    String destFullPath = destPath+FileUpload.SEPARATOR+realName;

                    boolean flag=false;
                    flag = FileUpload.moveFile(path,destFullPath);

                    if(!flag){
                        result.put("status",false);
                        result.put("code",0);
                        result.put("msg","移动文件失败，请检查Server文件！");
                        return result;
                    }
                    DepFileInfo data = new DepFileInfo();
                    data.setDepFileType(info.getDepFileType());
                    data.setDepFileName(realName);
                    data.setDepPath(destFullPath);
                    data.setCreateTime(FileUpload.sdf.format(new Date()));
                    data.setSuffix(suffix);
                    data.setDepArea(info.getDepArea());
                    //listInfo.add(data);
                    depFileInfoService.saveDepFileInfo(data);
                }

                if(true){
                    result.put("status",true);
                    result.put("code",0);
                    result.put("msg","上传成功！");
                }else{
                    result.put("status",false);
                    result.put("code",1);
                    result.put("msg","上传失败！");
                }

            }
            return result;
        } catch (Exception e) {
            result.put("status",false);
            result.put("code",1);
            result.put("msg","上传失败！");
            e.printStackTrace();
            return result;
        }
    }

}
